package com.admin.system.modules.system.rest;

import com.admin.common.constant.ExceptionConstant;
import com.admin.common.entity.BaseEntity;
import com.admin.common.exception.BadRequestException;
import com.admin.common.utils.PageResult;
import com.admin.common.utils.PageUtil;
import com.admin.component.web.MultipartFileUtil;
import com.admin.core.dto.MenuQueryDTO;
import com.admin.core.entity.SysMenu;
import com.admin.logging.annotation.Log;
import com.admin.logging.enums.OperateTypeEnum;
import com.admin.system.modules.system.dto.MenuTreeDTO;
import com.admin.system.modules.system.dto.MenuVo;
import com.admin.system.modules.system.service.MenuService;
import com.admin.system.modules.system.util.TreeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author sq-lan
 */
@RestController
@RequiredArgsConstructor
@Api(tags = "系统：菜单管理")
@RequestMapping("/api/menus")
public class MenuController {

    private final MenuService menuService;
    private static final String YES_STR = "是";
    private static final String NO_STR = "否";

    @GetMapping
    @ApiOperation("查询")
    @PreAuthorize("@ss.check('menu:list')")
    public ResponseEntity<PageResult<SysMenu>> list(MenuQueryDTO dto) {
        List<SysMenu> menuList = menuService.list(dto);
        return new ResponseEntity<>(PageUtil.toPage(menuList), HttpStatus.OK);
    }

    @GetMapping(value = "/menuBar")
    @ApiOperation("前端菜单栏")
    public ResponseEntity<List<MenuVo>> menuBar() {
        List<SysMenu> menuList = menuService.listMyFilterType(2);
        List<MenuTreeDTO> menus = TreeUtil.build(menuList);
        return new ResponseEntity<>(TreeUtil.handelMenuRoute(menus), HttpStatus.OK);
    }

    @GetMapping(value = "/listAll")
    @ApiOperation("所有菜单(根据自身权限)")
    @PreAuthorize("@ss.check('roles:list')")
    public ResponseEntity<List<SysMenu>> listAll() {
        List<SysMenu> menuList = menuService.listMyAll();
        return new ResponseEntity<>(menuList, HttpStatus.OK);
    }

    @ApiOperation("子菜单")
    @GetMapping(value = "/children")
    @PreAuthorize("@ss.check('menu:list','roles:list')")
    public ResponseEntity<List<SysMenu>> children(@RequestParam Integer id) {
        return new ResponseEntity<>(menuService.listByPid(id), HttpStatus.OK);
    }

    @Log(module = "菜单管理", operateType = OperateTypeEnum.ADD)
    @ApiOperation("新增菜单")
    @PostMapping
    @PreAuthorize("@ss.check('menu:add')")
    public ResponseEntity<Object> add(@Validated @RequestBody SysMenu entity) {
        if (entity.getId() != null) {
            throw new BadRequestException(ExceptionConstant.ERROR_PARAM);
        }
        menuService.add(entity);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

    @Log(module = "菜单管理", operateType = OperateTypeEnum.MODIFY)
    @ApiOperation("修改菜单")
    @PutMapping
    @PreAuthorize("@ss.check('menu:edit')")
    public ResponseEntity<Object> modify(@Validated(BaseEntity.Update.class) @RequestBody SysMenu entity) {
        menuService.modify(entity);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @Log(module = "菜单管理", operateType = OperateTypeEnum.REMOVE)
    @ApiOperation("删除菜单")
    @DeleteMapping
    @PreAuthorize("@ss.check('menu:del')")
    public ResponseEntity<Object> remove(@RequestBody Set<Integer> ids) {
        Set<SysMenu> menuSet = new HashSet<>();
        for (Integer id : ids) {
            List<SysMenu> menuList = menuService.listByPid(id);
            menuSet.add(menuService.getById(id));
            menuSet = menuService.listChildAllAndSelf(menuList, menuSet);
        }
        menuService.remove(menuSet);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("导出菜单数据")
    @GetMapping(value = "/download")
    @PreAuthorize("@ss.check('menu:list')")
    public void exportMenu(HttpServletResponse response, MenuQueryDTO dto) throws Exception {
        List<SysMenu> menus = menuService.list(dto);
        List<Map<String, Object>> list = new ArrayList<>();
        for (SysMenu menu : menus) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("菜单标题", menu.getTitle());
            map.put("菜单类型", menu.getType() == null ? "目录" : menu.getType() == 1 ? "菜单" : "按钮");
            map.put("权限标识", menu.getPermission());
            map.put("外链菜单", menu.getIFrame() ? YES_STR : NO_STR);
            map.put("菜单可见", menu.getHidden() ? NO_STR : YES_STR);
            map.put("是否缓存", menu.getCache() ? YES_STR : NO_STR);
            map.put("创建日期", menu.getCreateTime());
            list.add(map);
        }
        MultipartFileUtil.downloadExcel(list, response);
    }
}
